package com.vchangyi.springboot.common.interceptor;

import com.vchangyi.springboot.common.utils.AesUtil;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

@Intercepts({
    @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
@Component
public class DecryptionInterceptor implements Interceptor {

    private static final Pattern EMAIL_OR_MOBILE_PATTERN = Pattern.compile(".*?(email|mobile).*?", Pattern.CASE_INSENSITIVE);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();

        if (result instanceof List) {
            List<?> resultList = (List<?>) result;
            for (Object item : resultList) {
                if (item != null) {
                    if (item instanceof Map) {
                        decryptMapFields((Map<String, Object>) item);
                    } else {
                        decryptEntityFields(item);
                    }
                }
            }
        } else if (result != null) {
            if (result instanceof Map) {
                decryptMapFields((Map<String, Object>) result);
            } else {
                decryptEntityFields(result);
            }
        }

        return result;
    }

    private void decryptMapFields(Map<String, Object> map) throws Exception {
        for (String key : map.keySet()) {
            if (EMAIL_OR_MOBILE_PATTERN.matcher(key).matches() && map.get(key) instanceof String) {
                String value = (String) map.get(key);
                map.put(key, AesUtil.decrypt(value));
            }
        }
    }

    private void decryptEntityFields(Object obj) throws Exception {
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true);
            String fieldName = field.getName();
            if (EMAIL_OR_MOBILE_PATTERN.matcher(fieldName).matches() && field.get(obj) instanceof String) {
                String value = (String) field.get(obj);
                field.set(obj, AesUtil.decrypt(value));
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 可以在这里设置一些属性
    }
}